package org.destinyshine.cricket.context;

import org.apache.commons.lang3.StringUtils;
import org.destinyshine.cricket.container.WebApplicationContext;
import org.destinyshine.cricket.server.LifecycleListener;
import org.destinyshine.cricket.server.LifecycleListenerAdapter;

import javax.servlet.*;
import javax.servlet.RequestDispatcher;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

/**
 * Created by jianyu.liu@hnlark.com on 2016/6/5.
 *
 * @author jianyu.liu@hnlark.com
 */
public class WebApplicationContextFacade extends LifecycleListenerAdapter implements ServletContext, LifecycleListener {

    public static final int MAJOR_VERSION = 2;
    public static final int MINOR_VERSION = 5;

    private final WebApplicationContext internal;
    private final File contextBase;

    public WebApplicationContextFacade(WebApplicationContext internal) {
        this.internal = internal;
        this.contextBase = internal.getContextBase();
    }

    @Override
    public String getContextPath() {
        return internal.getContextPath();
    }

    @Override
    public ServletContext getContext(String uripath) {
        //TODO::getContext
        return null;
    }

    @Override
    public int getMajorVersion() {
        return MAJOR_VERSION;
    }

    @Override
    public int getMinorVersion() {
        return MINOR_VERSION;
    }

    @Override
    public String getMimeType(String file) {
        return null;
    }

    @Override
    public Set<String> getResourcePaths(String path) {
        if (StringUtils.isBlank(path)) {
            path = "/";
        } else if (path.charAt(0) != '/') {
            path = '/' + path;
        }

        File[] files = new File(contextBase, path).listFiles();
        Set<String> childrenPaths = new HashSet<>(files.length);
        for (File file : files) {
            String childPath = path + '/' + file.getName();
            if (file.isDirectory()) {
                childPath = childPath + '/';
            }
            childrenPaths.add(childPath);
        }
        return childrenPaths;
    }

    @Override
    public URL getResource(String path) throws MalformedURLException {
        return new File(contextBase, path).toURI().toURL();
    }

    @Override
    public InputStream getResourceAsStream(String path) {
        try {
            return getResource(path).openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public javax.servlet.RequestDispatcher getRequestDispatcher(String path) {
        return null;
    }

    @Override
    public RequestDispatcher getNamedDispatcher(String name) {
        return null;
    }

    @Override
    public Servlet getServlet(String name) throws ServletException {
        return null;
    }

    @Override
    public Enumeration getServlets() {
        return null;
    }

    @Override
    public Enumeration getServletNames() {
        return null;
    }

    @Override
    public void log(String msg) {

    }

    @Override
    public void log(Exception exception, String msg) {

    }

    @Override
    public void log(String message, Throwable throwable) {

    }

    @Override
    public String getRealPath(String path) {
        return new File(contextBase, path).getAbsolutePath();
    }

    @Override
    public String getServerInfo() {
        return null;
    }

    @Override
    public String getInitParameter(String name) {
        return internal.getContextParams().get(name);
    }

    @Override
    public Enumeration getInitParameterNames() {
        return Collections.enumeration(internal.getContextParams().keySet());
    }

    @Override
    public Object getAttribute(String name) {
        return internal.getAttribute(name);
    }

    @Override
    public Enumeration getAttributeNames() {
        return internal.getAttributeNames();
    }

    @Override
    public void setAttribute(String name, Object object) {
        internal.setAttribute(name, object);
    }

    @Override
    public void removeAttribute(String name) {
        internal.removeAttribute(name);
    }

    @Override
    public String getServletContextName() {
        return internal.getDisplayName();
    }
}
